<?php
/**
* 当前域名管理类
* @author moufer<moufer@163.com>
* @copyright (C)2001-2007 Moufersoft
*/
!defined('IN_MUDDER') && exit('Access Denied');

const MS_DOMAIN_TYPE_NORMAL		= 100;
const MS_DOMAIN_TYPE_IPADDRESS	= 110;
const MS_DOMAIN_TYPE_HOSTNAME	= 120;
const MS_DOMAIN_TYPE_UNKNOW		= 130;

class ms_domain
{
	/**
	 * 获取一个URL里的域名地址
	 * @param  string $url 一个完整的URL地址，留空表示获取当前正在访问的域名
	 * @param  boolean $keep_scheme    是否保留http前缀
	 * @param  string  $default_scheme 默认前缀是http://
	 * @return string
	 */
	public static function get_domain($url = '', $keep_scheme = false, $default_scheme = 'http', $filter_port = true)
	{
		if(!$url = trim($url)) {
			$url = strtolower($_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']);
		}
		$scheme = '';
		$port = '';

		$parse = parse_url($url);
		if(!$parse['scheme']) {
			$url = $default_scheme.'://'.$url;
			$parse = parse_url($url);
		}
		if($keep_scheme) {
			$scheme = ($parse['scheme']?:$default_scheme).'://';
		}
		if(!$filter_port&&$parse['port']&&$parse['port']!='80') {
			$port = ':'.$parse['port'];
		}
		return $scheme.strtolower($parse['host']).$port;
	}

	/**
	 * 获取子域名的上一级域名（3级返回2级，2级返回1级）
	 * 例如 www.modoer.com 返回 modoer.com，mp.weixin.qq.com 返回 weixin.qq.com，如果是 modoer.com 还是返回 modoer.com
	 * @param  string $domain_or_url [description]
	 * @return [type]                [description]
	 */
	public static function get_parent($domain_or_url = '')
	{
		$domain = trim(static::get_domain($domain_or_url), '.');
		$top_domain = static::get_top($domain);
		if($top_domain == $domain) return $domain;
		return substr($domain, strpos($domain, '.') + 1);
	}

	/**
	 * 获取一个域名或者完整URL的顶级域名（不包含www，例如modoer.com）
	 * @param  string $domain_or_url 一个域名或者完整的URL，留空表示当前域名
	 * @return [type]                [description]
	 */
	public static function get_top($domain_or_url = '')
	{
		static $library = null;
		if(is_null($library)) {
			$library = file_get_contents(MUDDER_DATA.'domain_library.inc');
			if($library) $library = str_replace('.', '\.', preg_replace("/\s*(\r\n|\n\r|\n|\r)\s*/", "|", $library));
			if(!$library) $library = 'com\.cn|com\.hk|net|com|cn|us|tw|hk';
		}
		$url = static::get_domain($domain_or_url);
		if(preg_match('/[\w][\w-]*\.(?:'.$library.')(\/|$)/isU', $url, $domain)) {
			return rtrim($domain[0], '/');
		}
		$url = str_replace('\\', '/', strtolower($url));
		if($i = strpos($url, '/')) {
			$url = substr($url, 0, $i);
		}
		if(filter_var($url, FILTER_VALIDATE_IP)) return $url;
		if(strposex($url, '/')) return false;
		if(strpos($url, '.') !== false) {
			$url = substr($url, strpos($url, '.') + 1);
		}
		return $url;
	}

	/**
	 * 获取一个域名的前缀
	 * @param  string $domain_or_url		一个域名或者完整的URL地址
	 * @param  string $ignore_www 		或略前缀是www的，即二级域名前缀是www，则返回空值
	 * @return string                
	 */
	public static function get_prefix($domain_or_url = '', $ignore_www = true)
	{
		$domain = static::get_domain($domain_or_url);

		$top_domain = static::get_top($domain);
		$prefix = rtrim(substr($domain, 0, -strlen($top_domain)), '.');

		if(!$prefix) return '';
		if($prefix == 'www' && $ignore_www) return '';
		return $prefix;
	}

	/**
	 * 获取指定URL地址的域名是什么类型的（正规域名，IP地址亦或者本机别名）
	 * @param  string $domain_or_url 一个域名或者完整的URL地址，留空表示获取当前域名
	 * @return integer
	 */
	public static function get_type($domain_or_url = '')
	{
		$domain = static::get_domain($domain_or_url);
		if(!$domain) {
			return MS_DOMAIN_TYPE_UNKNOW;
		} elseif(filter_var($domain, FILTER_VALIDATE_IP)) {
			return MS_DOMAIN_TYPE_IPADDRESS;
		} elseif(static::get_top($domain) && preg_match("/^([a-z0-9_\-\.]+)\.([a-z]{2,6})$/i", $domain)) {
			return MS_DOMAIN_TYPE_NORMAL;
		} else {
			return MS_DOMAIN_TYPE_HOSTNAME;
		}
	}

	/**
	 * 指定一个域名或完整的URL，对比是否和当前域名一致
	 * @param  string $domain_or_url 	一个需要进行对比的域名或完整的URL，留空表示与系统内填写的域名做对比
	 * @param  string $domain_or_url2 	一个需要进行对比的域名或完整的URL，留空表示当前访问的URL
	 * @param  bool $compare_top 	是否至对比顶级域名?（不对比2,3级域名）
	 * @return boolean
	 */
	public static function compare_with($domain_or_url = '', $domain_or_url2 = '', $compare_top = false)
	{
		$get_domain = $compare_top?'get_top':'get_domain';

		//未设置第1个对比的域名，则使用系统设置的域名
		$domain_or_url = $domain_or_url?:S('siteurl');
		$n_domain = static::$get_domain($domain_or_url);

		//未设置第二个对比的域名，则使用当前访问的域名
		$c_domain = strtolower(static::$get_domain($domain_or_url2));

		return $c_domain == $n_domain;
	}

	/**
	 * 删除一个连接里的域名，近保留URi参数
	 * @param  string $url
	 * @return string
	 */
	public static function remove_domain($url)
	{
		$arr = parse_url($url);
		if(!$arr) return $url;
		return $arr['path'].($arr['query']?"?{$arr['query']}":'');
	}
}

/**  */